﻿@*
//------------------------------------------------------------------------------
//  此代码版权声明为全文件覆盖，如有原作者特别声明，会在下方手动补充
//  此代码版权（除特别声明外的代码）归作者本人Diego所有
//  源代码使用协议遵循本仓库的开源协议及附加协议
//  Gitee源代码仓库：https://gitee.com/diego2098/ThingsGateway
//  Github源代码仓库：https://github.com/kimdiego2098/ThingsGateway
//  使用文档：https://diego2098.gitee.io/thingsgateway-docs/
//  QQ群：605534569
//------------------------------------------------------------------------------
*@

@page "/tgconfig/variable"
@namespace ThingsGateway.Web.Page
@using System.Linq.Expressions;
@using BlazorComponent;
@using Furion.DataValidation;
@using Mapster;
@using Masa.Blazor.Presets;
@using System.IO;
@using TouchSocket.Core;
@inject IVariableService VariableService
@attribute [Authorize]
@inject MasaBlazor MasaBlazor
@attribute [RolePermission]
@inherits CultureComponentBase
@inject UserResoures UserResoures
@inject ICollectDeviceService CollectDeviceService
@layout MainLayout

<MRow>
    <MCol Md=2 Cols="12">
        <MCard Class="ma-2" Style="height: calc(100vh - 200px)">
            <MCardTitle>
                <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="mx-2 my-1" @bind-Value="_searchName"
                            Outlined Label=@typeof(CollectDevice).GetDescription(nameof(CollectDevice.DeviceGroup)) />
            </MCardTitle>
            <MTreeview Style="height: calc(100vh - 320px);overflow-y:auto" Dense TItem="DeviceTree" TKey="string" OpenOnClick ActiveChanged=@(async a=>
                       {
                       if(search.DeviceName!=a.FirstOrDefault())
                       {
                       search.DeviceName=a.FirstOrDefault();
                       await datatableQuery();
                       }
                       } )
                       Items="_deviceGroups" ItemText="r=>r.Name" ItemChildren="r=>r.Childrens"
                       Search="@_searchName"
                       Activatable ItemKey=@(r=>r.Name)>
            </MTreeview>
        </MCard>
    </MCol>
    <MCol Md=10 Cols="12">
        <div style="height: calc(100vh - 200px)">

            <AppDataTable @ref="_datatable" TItem="CollectDeviceVariable" SearchItem="VariablePageInput"
                          AddItem="VariableAddInput" EditItem="VariableEditInput"
                          IsMenuOperTemplate=false SearchModel="search"
                          QueryCall="QueryCall" AddCall="AddCall" EditCall="EditCall" DeleteCall="DeleteCall"
                          FilterHeaders="FilterHeaders" Filters="Filters" ShowDetailButton
                                ShowQueryButton
                          ShowAddButton=@UserResoures.IsHasButtonWithRole("tgvariableadd")
                          ShowDeleteButton=@UserResoures.IsHasButtonWithRole("tgvariabledelete")
                          ShowEditButton=@UserResoures.IsHasButtonWithRole("tgvariableedit")>
                <SearchTemplate>
                    <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1  mx-2 " @bind-Value="context.Name" Clearable
                                        Outlined Label=@context.Description(x => x.Name) />
                    <MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1  mx-2 " @bind-Value="context.VariableAddress" Clearable
                                        Outlined Label=@context.Description(x => x.VariableAddress) />
                </SearchTemplate>
                <OtherToolbarTemplate>

                    <MButton Class="my-1  mx-2" Loading=@isDownExport OnClick=DownDeviceExport Color="primary">
                        @T("导出")
                    </MButton>

                    <MButton Disabled=@(!UserResoures.IsHasButtonWithRole("tgvariableedit")) Class="my-1  mx-2" OnClick="()=>{ ImportExcel.Step=1;  ImportExcel.IsShowImport=true;}" Color="primary">
                        @T("导入")
                    </MButton>
                    <MButton Disabled=@(!UserResoures.IsHasButtonWithRole("tgvariableedit")) Class="my-1  mx-2" OnClick=Clear Color="primary">
                        @T("清空")
                    </MButton>
                </OtherToolbarTemplate>
                <AddTemplate>
                    @{
                        var data = CollectDevices.FirstOrDefault();
                        context.DeviceId = context.DeviceId == 0 ? data == null ? 0 : data.Id : context.DeviceId;
                    }
                    @GetRenderFragment(context)
                </AddTemplate>
                <EditTemplate>
                    @GetRenderFragment(context)
                </EditTemplate>
                <ItemColTemplate>
                    @switch (context.Header.Value)
                    {
                        case nameof(context.Item.DeviceId):
                            <span>@CollectDeviceService.GetNameById(context.Item.DeviceId)</span>
                            break;
                        default:
                            @context.Value
                            break;

                    }

                </ItemColTemplate>
            </AppDataTable>


        </div>
    </MCol>
</MRow>

<ImportExcel @ref=ImportExcel Import="SaveDeviceImport" Preview="DeviceImport" />



@code {

    private VariablePageInput search = new();


    ImportExcel ImportExcel;
    async Task SaveDeviceImport(Dictionary<string, ImportPreviewOutputBase> data)
    {
        await VariableService.ImportAsync(data);
        await datatableQuery();
        ImportExcel.IsShowImport = false;
    }
    Task<Dictionary<string, ImportPreviewOutputBase>> DeviceImport(IBrowserFile file)
    {
        return VariableService.PreviewAsync(file);
    }

}
@code {
    [Inject] public JsInitVariables JsInitVariables { get; set; } = default!;
    [Inject]
    IJSRuntime JS { get; set; }
    bool isDownExport;
    async Task DownDeviceExport()
    {
        try
        {
            isDownExport = true;
            StateHasChanged();
            using var memoryStream = await VariableService.ExportFileAsync();
            memoryStream.Seek(0, SeekOrigin.Begin);
            using var streamRef = new DotNetStreamReference(stream: memoryStream);
            await JS.InvokeVoidAsync("downloadFileFromStream", $"变量导出{DateTime.UtcNow.Add(JsInitVariables.TimezoneOffset).ToString("MM-dd-HH-mm-ss")}.xlsx", streamRef);
        }
        finally
        {
            isDownExport = false;
        }
    }
}
    @code {
    StringNumber tab;
    List<CollectDevice> CollectDevices = new();
    List<UploadDevice> UploadDevices = new();
    Dictionary<long, List<string>> OtherMethods = new();
    void DeviceChanged(long devId)
    {
        if (devId > 0)
        {
            var data = ServiceExtension.GetBackgroundService<CollectDeviceWorker>().GetDeviceMethods(devId);
            OtherMethods.AddOrUpdate(devId, data);
        }
        else
            OtherMethods = new();
    }

    RenderFragment GetRenderFragment(VariableEditInput context)
    {
        if (!OtherMethods.ContainsKey(context.DeviceId))
        {
            DeviceChanged(context.DeviceId);
        }

        RenderFragment renderFragment = null;
        renderFragment +=
    @<div>
        <MTabs @bind-Value="tab">
            <MTab Style="height:50px;">   @T("基本属性")    </MTab>
            <MTab Style="height:50px;">    @T("报警属性")    </MTab>
            <MTab Style="height:50px;">    @T("历史属性")    </MTab>
            <MTab Style="height:50px;">    @T("上传属性")    </MTab>
        </MTabs>

        <MTabsItems Value="tab">
            <MTabItem>
                <MCard Flat Class="ma-2">
                    <MRow NoGutters Class="my-2" Justify="JustifyTypes.Start">
                        <MCol Md=12 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.Name))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.Name />
                        </MCol>


                        <MCol Md=12 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black">    @(context.Description(x => x.Description))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.Description />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black">    @context.Description(x=>x.DeviceId)  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.DeviceId Outlined
                                     Items=@(CollectDevices) OnClick=@(()=>DeviceChanged(context.DeviceId))
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.Name) ItemValue=@(u =>u.Id)
                                     ItemDisabled="u => !u.Enable"
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black">    @(context.Description(x => x.IntervalTime))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.IntervalTime />
                        </MCol>


                        <MCol Md=12 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black">    @(context.Description(x => x.VariableAddress))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.VariableAddress />
                        </MCol>



                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black">    @(context.Description(x => x.ProtectTypeEnum))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value="context.ProtectTypeEnum" Outlined
                                     Items=@(typeof(ProtectTypeEnum).GetEnumList())
                                     MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.des)
                                     ItemValue=@(u =>(ProtectTypeEnum)u.value)
                                     HideDetails=@("auto") Height="30"
                                          Dense>
                            </MSelect>
                        </MCol>


                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black">    @(context.Description(x => x.DataTypeEnum))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value="context.DataTypeEnum" Outlined
                                     Items=@(typeof(DataTypeEnum).GetEnumList()) Clearable
                                     MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.des)
                                     ItemValue=@(u =>(DataTypeEnum)u.value)
                                     HideDetails=@("auto") Height="30"
                                          Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">

                            <MSubheader Class="font-weight-black">    @(context.Description(x => x.ReadExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.ReadExpressions />
                        </MCol>
                        <MCol Md=6 Cols=12 class="px-1">

                            <MSubheader Class="font-weight-black">    @(context.Description(x => x.WriteExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.WriteExpressions />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.RpcWriteEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.RpcWriteEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>


                        @if (OtherMethods.ContainsKey(context.DeviceId))
                        {

                            <MCol Md=12 Cols=12 class="px-1">
                                <MSubheader Class="font-weight-black">    @(context.Description(x => x.OtherMethod))  </MSubheader>
                                <MSelect Class="mr-3" @bind-Value="context.OtherMethod" Outlined
                                             Items=@(OtherMethods[context.DeviceId]) Clearable
                                             MenuProps="@(props => { props.Auto = true; props.OffsetY = true; })"
                                             ItemText=@((u) =>u)
                                             ItemValue=@(u =>u)
                                             HideDetails=@("auto") Height="30"
                                                  Dense>
                                </MSelect>
                            </MCol>

                        }

                    </MRow>

                </MCard>
            </MTabItem>

            <MTabItem>
                <MCard Flat Class="ma-2">
                    <MRow NoGutters Class="my-2" Justify="JustifyTypes.Center">

                        <MCol Md=12 Cols=12 class="px-1 py-2">
                            <MDivider Center Height="2"></MDivider>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.BoolCloseAlarmEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.BoolCloseAlarmEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.BoolCloseAlarmText))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.BoolCloseAlarmText />
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.BoolCloseRestrainExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.BoolCloseRestrainExpressions />
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1 py-2">
                            <MDivider Center Height="2"></MDivider>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.BoolOpenAlarmEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.BoolOpenAlarmEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>


                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.BoolOpenAlarmText))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.BoolOpenAlarmText />
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.BoolOpenRestrainExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.BoolOpenRestrainExpressions />
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1 py-2">
                            <MDivider Center Height="2"></MDivider>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HHAlarmEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.HHAlarmEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HHAlarmText))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.HHAlarmText />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HHAlarmCode))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.HHAlarmCode />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HHRestrainExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.HHRestrainExpressions />
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1 py-2">
                            <MDivider Center Height="2"></MDivider>
                        </MCol>


                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HAlarmEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.HAlarmEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HAlarmText))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.HAlarmText />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HAlarmCode))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.HAlarmCode />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1 py-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HRestrainExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.HRestrainExpressions />
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1 py-2">
                            <MDivider Center Height="2"></MDivider>
                        </MCol>
                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LAlarmEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.LAlarmEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LAlarmText))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.LAlarmText />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LAlarmCode))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.LAlarmCode />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LRestrainExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.LRestrainExpressions />
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1 py-2">
                            <MDivider Center Height="2"></MDivider>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LLAlarmEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.LLAlarmEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LLAlarmText))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.LLAlarmText />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LLAlarmCode))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.LLAlarmCode />
                        </MCol>

                        <MCol Md=6 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.LLRestrainExpressions))  </MSubheader>
                            <MTextField Dense Outlined HideDetails="@("auto")" @bind-Value=@context.LLRestrainExpressions />
                        </MCol>


                    </MRow>

                </MCard>
            </MTabItem>


            <MTabItem>
                <MCard Flat Class="ma-2">

                    <MRow NoGutters Class="my-2" Justify="JustifyTypes.Center">
                        <MCol Md=12 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HisEnable))  </MSubheader>
                            <MSelect Class="mr-3" @bind-Value=@context.HisEnable Outlined
                                     Items=@(new List<bool>(){true,false}) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.ToString()) ItemValue=@(u =>u)
                                     HideDetails=@("auto") Height="30" Dense>
                            </MSelect>
                        </MCol>

                        <MCol Md=12 Cols=12 class="px-1">
                            <MSubheader Class="font-weight-black"> @(context.Description(x => x.HisType))  </MSubheader>

                            <MSelect Class="mr-3" @bind-Value=@context.HisType Outlined
                                     Items=@(typeof(HisType).GetEnumList()) Clearable
                                     MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                     ItemText=@((u) =>u.des)
                                     ItemValue=@(u =>(HisType)u.value)
                                     HideDetails=@("auto") Height="30"
                                          Dense>
                            </MSelect>
                        </MCol>

                    </MRow>

                </MCard>
            </MTabItem>
            <MTabItem>
                <MCard Flat Class="pa-2">
                    <MRow Class="px-1 py-6" Align="AlignTypes.Center">

                        <MSelect Class="mr-3" @bind-Value=@choiceUploadDeviceId Outlined
                                 Items=@(UploadDevices) Clearable
                                 MenuProps="@(props => { props.Bottom = true; props.OffsetY = true; })"
                                 ItemText=@((u) =>u.Name) ItemValue=@(u =>u.Id)
                                 HideDetails=@("auto") Height="30" Dense>
                        </MSelect>
                        <MButton Class="my-3" OnClick=@(async() =>
                             {
                             if(choiceUploadDeviceId>0)
                             {
                             var data=GetDriverProperties(UploadDevices.FirstOrDefault(a=>a.Id==choiceUploadDeviceId).PluginId,context.VariablePropertys.ContainsKey(choiceUploadDeviceId)?context.VariablePropertys[choiceUploadDeviceId]:null);
                             if(data?.Count>0)
                             {
                             context.VariablePropertys.AddOrUpdate(choiceUploadDeviceId, data);
                             }
                             else
                             {
                             await PopupService.EnqueueSnackbarAsync("此上传设备没有变量上传属性",AlertTypes.Warning);
                             context.VariablePropertys.Remove(choiceUploadDeviceId);
                             }
                             }
                             else
                             {
                             await PopupService.EnqueueSnackbarAsync("需选择上传设备",AlertTypes.Warning);
                             }
                             }
                             ) Color="primary">
                            @T("添加/刷新属性")
                        </MButton>

                    </MRow>
                    @if (context.VariablePropertys != null)
                    {
                        @foreach (var item in context.VariablePropertys)
                        {
                            <MCard Class="pa-2 my-3">

                                <MSubheader Class="mt-4 font-weight-black"> @(UploadDevices.FirstOrDefault(a => a.Id == item.Key)?.Name ?? "未知") </MSubheader>
                                @foreach (var property in item.Value ?? new())
                                {
                                    <MSubheader Class="mt-4 font-weight-black"> @property.Description </MSubheader>
                                    <MTooltip Disabled=property.Remark.IsNullOrEmpty() Bottom Context="tip">
                                            <ActivatorContent>
                                                <MTextField @attributes="@tip.Attrs" Dense Outlined HideDetails="@("auto")" @bind-Value=@property.Value />
                                            </ActivatorContent>
                                            <ChildContent>
                                                <span>@property.Remark</span>
                                            </ChildContent>
                                        </MTooltip>
                                }
                                <MCardActions>
                                    <MButton Class="my-3" OnClick=@(() =>
                                 {
                                 context.VariablePropertys.Remove(item.Key);
                                 }
                                 ) Color="primary">
                                        @T("删除")
                                    </MButton>
                                </MCardActions>
                            </MCard>
                        }


                    }
                </MCard>
            </MTabItem>
        </MTabsItems>

    </div>
    ;
        return renderFragment;
    }
}
@code {
    string _searchName;
    List<DeviceTree> _deviceGroups = new();

    long choiceUploadDeviceId;
    List<DependencyProperty> GetDriverProperties(long driverId, List<DependencyProperty> dependencyProperties)
    {
        return ServiceExtension.GetBackgroundService<UploadDeviceWorker>().GetVariablePropertys(driverId, dependencyProperties);
    }
}